#region Copyright (c) 2006-2012 nHydrate.org, All Rights Reserved
// --------------------------------------------------------------------- *
//                           NHYDRATE.ORG                                *
//              Copyright (c) 2006-2012 All Rights reserved              *
//                                                                       *
//                                                                       *
// This file and its contents are protected by United States and         *
// International copyright laws.  Unauthorized reproduction and/or       *
// distribution of all or any portion of the code contained herein       *
// is strictly prohibited and will result in severe civil and criminal   *
// penalties.  Any violations of this copyright will be prosecuted       *
// to the fullest extent possible under law.                             *
//                                                                       *
// THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
// TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
// TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
// CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
// THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF THE NHYDRATE GROUP *
//                                                                       *
// UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
// PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
// SUBSTANTIALLY THE SAME, FUNCTIONALITY AS THIS PRODUCT                 *
//                                                                       *
// THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
// CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF NHYDRATE,          *
// THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO             *
// INSURE ITS CONFIDENTIALITY.                                           *
//                                                                       *
// THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
// PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
// EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
// THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
// SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                       *
// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
// --------------------------------------------------------------------- *
#endregion
using System;
using System.IO;
using nHydrate.Generator.Common.GeneratorFramework;
using nHydrate.Generator.Common.Util;
using nHydrate.Generator.Models;

namespace nHydrate.Generator.ProjectItemGenerators
{
	public abstract class BaseProjectGenerator : IProjectGenerator
	{
		protected ModelRoot _model;

		protected abstract string ProjectTemplate { get;}
		public abstract string LocalNamespaceExtension { get; }

		public virtual string ProjectName
		{
			get { return this.GetLocalNamespace(); }
		}

		public virtual string DefaultNamespace
		{
			get { return nHydrateGeneratorProject.DomainProjectName(_model); }
		}

		public virtual string GetLocalNamespace()
		{
			if (string.IsNullOrEmpty(this.LocalNamespaceExtension))
				return this.DefaultNamespace;
			else
				return this.DefaultNamespace + "." + this.LocalNamespaceExtension;
		}

		protected virtual void OnAfterGenerate()
		{
			//Implement base functionality if needed
		}

		protected virtual void OnInitialize(IModelObject model)
		{
			//Implement base functionality if needed
		}

		#region IProjectGenerator Members

		public void Initialize(IModelObject model)
		{
			_model = (ModelRoot)model;
			OnInitialize(model);
		}

		public virtual void CreateProject()
		{
			var templateFullName = string.Empty;
			try
			{
				//If there is no project defined then do nothing
				if (string.IsNullOrEmpty(this.ProjectTemplate))
					return;

				var newProject = EnvDTEHelper.Instance.GetProject(ProjectName);
				if (newProject != null)
					newProject.Delete();

				templateFullName = Path.Combine(AddinAppData.Instance.ExtensionDirectory, this.ProjectTemplate);

				//Copy the template and project file to a temp folder and perform replacements
				var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
				Directory.CreateDirectory(tempPath);

				//Copy template
				var fi = new FileInfo(templateFullName);
				var targetFile = Path.Combine(tempPath, fi.Name);
				File.Copy(templateFullName, targetFile, true);

				//Copy project
				var sourceFile = templateFullName.Replace(".vstemplate", ".csproj");
				fi = new FileInfo(sourceFile);
				if (File.Exists(sourceFile))
				{
					targetFile = Path.Combine(tempPath, fi.Name);
					File.Copy(sourceFile, targetFile, true);
					fi = new FileInfo(targetFile);
					this.GenerateCompanySpecificFile(tempPath, fi.Name);
				}

				//Copy the assembly file over
				sourceFile = Path.Combine(AddinAppData.Instance.ExtensionDirectory, "AssemblyInfo.cs");
				if (File.Exists(sourceFile))
				{
					var propertyPath = Path.Combine(tempPath, "Properties");
					Directory.CreateDirectory(propertyPath);
					var t = Path.Combine(propertyPath, "AssemblyInfo.cs");
					File.Copy(sourceFile, t, true);
					fi = new FileInfo(t);
					this.GenerateCompanySpecificFile(propertyPath, fi.Name);
				}

				newProject = EnvDTEHelper.Instance.CreateProjectFromTemplate(targetFile, this.ProjectName, this._model.OutputTarget);
				Directory.Delete(tempPath, true);
				OnAfterGenerate();
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		private void GenerateCompanySpecificFile(string tempPath, string fileName)
		{
			try
			{
				var defaultProjectTemplate = Path.Combine(tempPath, fileName);
				var fileData = File.ReadAllText(defaultProjectTemplate);

				var newFileText = fileData.Replace("Acme", _model.CompanyName);
				newFileText = newFileText.Replace("$generatedproject$", this.DefaultNamespace);
				newFileText = newFileText.Replace("$safeprojectname$", this.GetLocalNamespace());
				newFileText = newFileText.Replace("$registeredorganization$", _model.CompanyName);
				newFileText = newFileText.Replace("$projectname$", this.GetLocalNamespace());
				newFileText = newFileText.Replace("$year$", DateTime.Now.Year.ToString());
				newFileText = newFileText.Replace("$guid1$", Guid.NewGuid().ToString());

				File.WriteAllText(defaultProjectTemplate, newFileText);
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		#endregion

	}
}
